home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CICA Windows Explosion!
/
The CICA Windows Explosion! - Disc 2.iso
/
programr
/
tabdlg2.zip
/
SRC
/
TABDLG.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-17
|
23KB
|
1,098 lines
/*
** TabDlg DLL
** Copyright (c) 1994 Edward McCreary.
** All rights reserved.
**
** Redistribution and use in source and binary forms are freely permitted
** provided that the above copyright notice and attibution and date of work
** and this paragraph are duplicated in all such forms.
** THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
** WARRANTIES OF MERCHANTIBILILTY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#define STRICT
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include "tabdlg2.h"
#include "common.h"
#include "dyndlg.h"
static HINSTANCE hInst; /* instance handle of the dll */
/*
** store tab data here,
** referenced by dialog handle
*/
static FRAME_ENTRY entries[MAX_ENTRY];
static int nNextEntry = 0; /* next empty entry */
/* height of tab */
#define TAB_HEIGHT 20
/* pens used to draw with */
static HPEN pens[3];
#define PEN_BLACK 0
#define PEN_WHITE 1
#define PEN_SHADOW 2
/* font used for depressed tabs */
HFONT hFont = NULL;
/*
**
** Library Entry point
**
*/
BOOL WINAPI LibMain (HINSTANCE hInstance, WORD wDataSeg,
WORD wHeapSize, LPSTR lpszCmdLine)
{
if(wHeapSize != 0)
UnlockData(0);
/* store off dll instance handle */
hInst = hInstance;
/* to keep the compiler from bitching */
wDataSeg = wDataSeg;
lpszCmdLine = lpszCmdLine;
return TRUE;
}
/*
**
** Lookup tab structure by id of tab
**
*/
TAB_ENTRY __export *GetTabEntry(FRAME_ENTRY *pFrame,int nTabID)
{
TAB_ENTRY *ptr;
/* get list of tabs in this frame */
ptr = pFrame->tab_list;
/* while not end of list */
while(ptr)
{
if(ptr->nTabID == nTabID) /* if id's match, return pointer to tab */
return ptr;
/* walk down list */
ptr = ptr->next;
}
/* return null if tab not found */
return NULL;
}
/*
**
** Lookup internal structure of frame given dialog handle
**
*/
FRAME_ENTRY __export *GetFrameEntry(HWND hDlg)
{
static HWND hDlgCache = NULL;
static FRAME_ENTRY *pFrameCache = NULL;
FRAME_ENTRY *pFrame = NULL;
int i;
/* if cached */
if(hDlg == hDlgCache)
return pFrameCache;
for(i = 0; i < nNextEntry; i++)
if(entries[i].hDlg == hDlg)
{
pFrame = &entries[i];
break;
}
hDlgCache = hDlg;
pFrameCache = pFrame;
return pFrame;
}
/*
**
** Set tab nTabID to be the top tab
**
*/
BOOL WINAPI __export SetTopTab(HWND hDlg, int nTabID)
{
FRAME_ENTRY *pFrame;
TAB_ENTRY *pTab;
TAB_CTL *pControl;
UINT uFlags;
/* get data for this frame */
pFrame = GetFrameEntry(hDlg);
/* abort if not found */
if(!pFrame)
return FALSE;
/* save id of new top tab */
pFrame->nTopTab = nTabID;
/* common flags */
uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOSIZE |
SWP_NOZORDER;
/* get pointer to list of tabs */
pTab = pFrame->tab_list;
/*
**
** loop through list, hide or show each one, then do an invalidate rect
** and updatewindow to force repaint. this is cleaner than using ShowWindow
** for each control.
**
*/
/* while not at end of list */
while(pTab)
{
pControl = pTab->controls; /* get pointer to list controls in this tab */
/* while not at end of list */
while(pControl)
{
if(pTab->nTabID == nTabID) /* if new top tab, show control */
SetWindowPos(GetDlgItem(pFrame->hDlg,pControl->wID),NULL,0,0,0,0,
uFlags | SWP_SHOWWINDOW);
else /* else hide him */
SetWindowPos(GetDlgItem(pFrame->hDlg,pControl->wID),NULL,0,0,0,0,
uFlags | SWP_HIDEWINDOW);
/* get next control in list */
pControl = pControl->next;
}
/* get next tab in list */
pTab = pTab->next;
}
return TRUE;
}
/*
**
** get id of last tab in the frame list
**
*/
int __export GetLastTab(FRAME_ENTRY *pFrame)
{
TAB_ENTRY *pTab;
/* get point to list of tabs */
if(pFrame->tab_list)
{
/* walk to the end of the list */
pTab = pFrame->tab_list;
while(pTab->next)
pTab = pTab->next;
/* return id */
return pTab->nTabID;
}
/* return -1 if failed */
return -1;
}
/*
**
** detect if mouse hit a tab
**
*/
int TabHit(HWND hDlg,WORD x, WORD y)
{
FRAME_ENTRY *pFrame;
TAB_ENTRY *pTab;
int nWidth;
POINT pt;
RECT rc;
int nFrameLeft;
/* get frame data for this dialog box */
pFrame = GetFrameEntry(hDlg);
/* abort if not found */
if(!pFrame)
return -1;
/* get rectangle of frame control */
GetWindowRect(pFrame->hWnd,&rc);
/* convert to client coordinates (dialog client) */
pt.x = rc.left;
pt.y = rc.top;
ScreenToClient(pFrame->hDlg,&pt);
/* bottom of hit rectangle is top of frame control */
rc.bottom = pt.y;
/* top is TAB_HEIGHT above bottom */
rc.top = rc.bottom - TAB_HEIGHT;
/* store left edge of the frame */
rc.left = nFrameLeft = pt.x;
pt.x = rc.right;
pt.y = rc.bottom;
ScreenToClient(pFrame->hDlg,&pt);
rc.right = pt.x;
/* store point where mouse clicked */
pt.x = x;
pt.y = y;
/* quick test, if not in rectangle above frame, no sense trying the
** others
*/
if(!PtInRect(&rc,pt))
return -1;
/* get the width of one tab */
nWidth = GetTabWidth(pFrame);
/* get pointer to list of tabs */
pTab = pFrame->tab_list;
/* while not end of list */
while(pTab)
{
/* calc left edge of this tab */
rc.left = nFrameLeft + pTab->nTabID*nWidth;
/* right edge is simple nWidth over from left edge */
rc.right = rc.left + nWidth;
/* if hit, return id */
if(PtInRect(&rc,pt))
return pTab->nTabID;
/* get next tab in list */
pTab = pTab->next;
}
/* return -1 if none hit */
return -1;
}
/*
**
** find the width of a tab
**
*/
int GetTabWidth(FRAME_ENTRY *pFrame)
{
int nNumTabs;
int nWidth;
RECT rc;
/* if only one tab, don't want it to extend the
** entire length, use 2 instead
*/
nNumTabs = (pFrame->nNextTab < 2?2:pFrame->nNextTab);
/* get rectange of frame control */
GetWindowRect(pFrame->hWnd,&rc);
/* width of a tab is width of frame divided by the number of tabs */
nWidth = (rc.right - rc.left)/nNumTabs;
return nWidth;
}
/*
**
** First time registration
**
*/
void __export RegisterLibrary(void)
{
LOGFONT logfont;
/* store handles to pens used to draw tabs */
pens[PEN_BLACK] = (HPEN)GetStockObject(BLACK_PEN);
pens[PEN_WHITE] = (HPEN)GetStockObject(WHITE_PEN);
pens[PEN_SHADOW] = CreatePen(PS_SOLID,1,GetSysColor(COLOR_BTNSHADOW));
/* create font used to draw depressed tab titles */
memset(&logfont,0,sizeof(LOGFONT));
logfont.lfHeight = -13;
logfont.lfWeight = FW_NORMAL;
lstrcpy(logfont.lfFaceName,"Arial");
hFont = CreateFontIndirect(&logfont);
/* if unable to create font, just use system font */
if(!hFont)
hFont = (HFONT)GetStockObject(SYSTEM_FONT);
}
/*
**
** Remove frame from list and free associated resources
**
*/
void __export UnRegisterFrame(HWND hWnd)
{
int i,j;
TAB_ENTRY *ptr;
TAB_ENTRY *ptr_next;
FRAME_ENTRY *pFrame = NULL;
/* walk list of frames, find this one */
for(i = 0; i < nNextEntry; i++)
if(entries[i].hWnd == hWnd)
{
pFrame = &entries[i];
break;
}
/* if not found, abort */
if(!pFrame)
return;
/* restore original window proc for frame */
SetWindowLong(hWnd,GWL_WNDPROC,
(DWORD)entries[i].OldWndProc);
/* restore original window proc for dialog */
SetWindowLong(entries[i].hDlg,GWL_WNDPROC,
(DWORD)entries[i].OldDlgProc);
/* walk list of tabs and free memory for each */
ptr = pFrame->tab_list;
while(ptr)
{
ptr_next = ptr->next;
FreeTab(ptr);
ptr = ptr_next;
}
/* slide all entries above this one down one notch in list */
for(j = i; j < MAX_ENTRY; j++)
entries[j] = entries[j+1];
/* decrement entry counter */
nNextEntry--;
/* if none currently registered, free global resources */
if(nNextEntry == 0)
UnRegisterLibrary();
}
/*
**
** free up memory used with tab
**
*/
void FreeTab(TAB_ENTRY *pTab)
{
TAB_CTL *ptr;
TAB_CTL *ptr_next;
/* free memory used to store title */
free((void *)pTab->name);
/* walk list of controls and free memory assoc. with each */
ptr = pTab->controls;
while(ptr)
{
ptr_next = ptr->next;
free((void *)ptr);
ptr = ptr_next;
}
/* free tab memory */
free((void *)pTab);
}
/*
**
** last time deregistration
**
*/
void __export UnRegisterLibrary(void)
{
DeleteObject(pens[PEN_SHADOW]);
DeleteObject(hFont);
}
/*
**
** force repaint of tabs
**
*/
void UpdateTabs(HWND hDlg)
{
InvalidateRect(hDlg,NULL,TRUE);
UpdateWindow(hDlg);
}
/*
**
** paint the frame control
**
*/
void __export PaintFrame(FRAME_ENTRY *pFrame)
{
RECT rc;
POINT pt[4];
HPEN hOldPen;
HDC hdc;
/* get rect of frame control */
GetWindowRect(pFrame->hWnd,&rc);
/* convert to client coordinates of dialog box */
pt[0].x = rc.left;
pt[0].y = rc.top;
ScreenToClient(pFrame->hDlg,&pt[0]);
rc.left = pt[0].x;
rc.top = pt[0].y;
pt[0].x = rc.right;
pt[0].y = rc.bottom;
ScreenToClient(pFrame->hDlg,&pt[0]);
rc.right = pt[0].x;
rc.bottom = pt[0].y;
/* get a dc to the dialog box */
hdc = GetDC(pFrame->hDlg);
/* now draw the u shaped frame */
hOldPen = SelectObject(hdc, pens[PEN_BLACK]);
// black frame
pt[0].x = rc.left;
pt[0].y = rc.top;
pt[1].x = rc.left;
pt[1].y = rc.bottom;
pt[2].x = rc.right;
pt[2].y = rc.bottom;
pt[3].x = rc.right;
pt[3].y = rc.top-1; // make sure they connect
Polyline(hdc,(LPPOINT)&pt,4);
SelectObject(hdc,pens[PEN_WHITE]);
// two white border lines
pt[0].x = rc.left+1;
pt[0].y = rc.top;
pt[1].x = rc.left+1;
pt[1].y = rc.bottom-1;
Polyline(hdc,(LPPOINT)&pt,2);
pt[0].x = rc.left+2;
pt[0].y = rc.top;
pt[1].x = rc.left+2;
pt[1].y = rc.bottom-2;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,pens[PEN_SHADOW]);
// two shadow lines
pt[0].x = rc.left + 1;
pt[0].y = rc.bottom - 1;
pt[1].x = rc.right-1;
pt[1].y = rc.bottom - 1;
pt[2].x = rc.right - 1;
pt[2].y = rc.top - 1;
Polyline(hdc,(LPPOINT)&pt,3);
pt[0].x = rc.left + 2;
pt[0].y = rc.bottom - 2;
pt[1].x = rc.right-2;
pt[1].y = rc.bottom - 2;
pt[2].x = rc.right - 2;
pt[2].y = rc.top - 1;
Polyline(hdc,(LPPOINT)&pt,3);
/* restore old pen */
SelectObject(hdc,hOldPen);
/* paint tabs above the frame */
PaintTabs(pFrame,hdc,&rc);
/* give dc back to system */
ReleaseDC(pFrame->hDlg,hdc);
}
/*
**
** draw the tabs on top of the frame
**
*/
void __export PaintTabs(FRAME_ENTRY *pFrame,HDC hdc,LPRECT lprc)
{
RECT rcTab;
int nWidth;
TAB_ENTRY *pTab;
int nFrameLeft;
int nLastTab;
POINT pt[6];
HPEN hOldPen;
/* store left edge of frame */
nFrameLeft = lprc->left;
/* set top and bottom limits of tabs */
rcTab.bottom = lprc->top;
rcTab.top = rcTab.bottom - TAB_HEIGHT;
/* get width of single tab */
nWidth = GetTabWidth(pFrame);
/* index of last tab in list */
nLastTab = GetLastTab(pFrame);
/* paint each tab */
pTab = pFrame->tab_list;
while(pTab)
{
/* set left and right limits of this tab */
rcTab.left = nFrameLeft + pTab->nTabID*nWidth;
rcTab.right = rcTab.left + nWidth;
// if last tab, expand rect to end of frame
// but not if last tab == first tab
if(pTab->nTabID != 0 && pTab->nTabID == nLastTab)
rcTab.right = lprc->right;
/* if tab is top tab, draw it in up position */
if(pFrame->nTopTab == pTab->nTabID)
{
PaintUpTab(hdc,&rcTab);
DrawTabText(hdc,&rcTab,(LPCSTR)pTab->name,TRUE,pFrame->bUseShadow);
if(GetFocus() == pFrame->hWnd)
DrawFocusRect(hdc,&rcTab);
}
else
/* draw in down position */
{
PaintDownTab(hdc,&rcTab);
DrawTabText(hdc,&rcTab,(LPCSTR)pTab->name,FALSE,pFrame->bUseShadow);
}
/* loop to next tab in list */
pTab = pTab->next;
}
/* draw horz lines */
/* this make lower tabs appear below top tab */
/*
** if top tab not first in list, draw lines from left edge of
** frame to left edge of top tab
*/
if(pFrame->nTopTab != 0)
{
hOldPen = SelectObject(hdc,pens[PEN_BLACK]);
pt[0].x = lprc->left+1;
pt[0].y = lprc->top;
pt[1].x = pFrame->nTopTab*nWidth + nFrameLeft;
pt[1].y = lprc->top;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,pens[PEN_WHITE]);
pt[1].x = pFrame->nTopTab*nWidth + nFrameLeft + 3;
pt[0].y = lprc->top + 1;
pt[1].y = lprc->top + 1;
Polyline(hdc,(LPPOINT)&pt,2);
pt[0].y = lprc->top + 2;
pt[1].y = lprc->top + 2;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,hOldPen);
}
/* if not end of list or if only one tab */
/*
** draw lines from right edge of last tab to right edge
** of frame
*/
if(pFrame->nTopTab != nLastTab || nLastTab == 0)
{
hOldPen = SelectObject(hdc,pens[PEN_BLACK]);
pt[0].x = pFrame->nTopTab*nWidth + nFrameLeft + nWidth;
pt[0].y = lprc->top;
pt[1].x = lprc->right;
pt[1].y = lprc->top;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,pens[PEN_WHITE]);
pt[0].y++;
pt[1].y++;
Polyline(hdc,(LPPOINT)&pt,2);
pt[0].x--;
pt[0].y++;
pt[1].x--;
pt[1].y++;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,pens[PEN_SHADOW]);
pt[0].y--;
pt[1].y = pt[0].y;
pt[1].x = pt[0].x - 1;
pt[2].x = pt[1].x;
pt[2].y = pt[1].y + 2;
Polyline(hdc,(LPPOINT)&pt,3);
SelectObject(hdc,hOldPen);
}
}
/*
**
** draw the text in the tab
**
*/
void DrawTabText(HDC hdc,LPRECT lprc,LPCSTR text,BOOL bTop, BOOL bShadow)
{
RECT rc;
COLORREF cwOld;
HFONT hOldFont;
int nOldBkMode;
UINT uTextStyle = DT_SINGLELINE | DT_VCENTER | DT_CENTER;
/* let background color show */
nOldBkMode = SetBkMode(hdc,TRANSPARENT);
/* don't screw up lprc */
CopyRect(&rc,lprc);
/* to account for borders */
InflateRect(&rc,-5,-4);
/* shift down and to the right */
OffsetRect(&rc,1,1);
/* draw white text to give chisled look */
cwOld = SetTextColor(hdc,RGB(0xFF,0xFF,0xFF));
/* use small font for depressed tabs */
if(!bTop)
hOldFont = SelectObject(hdc,hFont);
if(bShadow) /* only draw if shadow enabled */
DrawText(hdc,text,-1,&rc,uTextStyle);
/* shift up and to the right */
OffsetRect(&rc,-1,-1);
/* use black text */
SetTextColor(hdc,RGB(0x00,0x00,0x00));
DrawText(hdc,text,-1,&rc,uTextStyle);
/* restore original font if needed */
if(!bTop)
SelectObject(hdc,hOldFont);
/* restore old text color */
SetTextColor(hdc,cwOld);
/* restore old background mode */
SetBkMode(hdc,nOldBkMode);
}
/*
**
** draw a top tab
**
*/
void __export PaintUpTab(HDC hdc, LPRECT lprc)
{
POINT pt[6];
HPEN hOldPen;
/* top tab is just the down tab with some extra lines */
PaintDownTab(hdc,lprc);
hOldPen = SelectObject(hdc,pens[PEN_WHITE]);
pt[0].x = lprc->left + 2;
pt[0].y = lprc->bottom;
pt[1].x = lprc->left + 2;
pt[1].y = lprc->top + 4;
pt[2].x = lprc->left + 4;
pt[2].y = lprc->top + 2;
pt[3].x = lprc->right - 4;
pt[3].y = lprc->top + 2;
Polyline(hdc,(LPPOINT)&pt,4);
pt[0].x = lprc->left + 3;
pt[0].y = lprc->top + 4;
pt[1].x = lprc->left + 5;
pt[1].y = lprc->top + 2;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,pens[PEN_SHADOW]);
pt[0].x = lprc->right - 4 ;
pt[0].y = lprc->top + 2;
pt[1].x = lprc->right - 2;
pt[1].y = lprc->top + 4;
pt[2].x = lprc->right - 2;
pt[2].y = lprc->bottom + 1;
Polyline(hdc,(LPPOINT)&pt,3);
pt[0].x = lprc->right - 4 ;
pt[0].y = lprc->top + 3;
pt[1].x = lprc->right - 2 ;
pt[1].y = lprc->top + 5;
Polyline(hdc,(LPPOINT)&pt,2);
SelectObject(hdc,hOldPen);
}
/*
**
** draw a down tab
**
*/
void __export PaintDownTab(HDC hdc, LPRECT lprc)
{
POINT pt[6];
HPEN hOldPen;
hOldPen = SelectObject(hdc,pens[PEN_BLACK]);
pt[0].x = lprc->left;
pt[0].y = lprc->bottom;
pt[1].x = lprc->left;
pt[1].y = lprc->top + 4;
pt[2].x = lprc->left + 4;
pt[2].y = lprc->top;
pt[3].x = lprc->right - 4;
pt[3].y = lprc->top;
pt[4].x = lprc->right;
pt[4].y = lprc->top + 4;
pt[5].x = lprc->right;
pt[5].y = lprc->bottom;
Polyline(hdc,(LPPOINT)&pt,6);
SelectObject(hdc,pens[PEN_WHITE]);
pt[0].x = lprc->left + 1;
pt[0].y = lprc->bottom;
pt[1].x = lprc->left + 1;
pt[1].y = lprc->top + 4;
pt[2].x = lprc->left + 4;
pt[2].y = lprc->top + 1;
pt[3].x = lprc->right - 3;
pt[3].y = lprc->top + 1;
Polyline(hdc,(LPPOINT)&pt,4);
SelectObject(hdc,pens[PEN_SHADOW]);
pt[0].x = lprc->right - 3 ;
pt[0].y = lprc->top + 2;
pt[1].x = lprc->right - 1;
pt[1].y = lprc->top + 4;
pt[2].x = lprc->right - 1;
pt[2].y = lprc->bottom + 1;
Polyline(hdc,(LPPOINT)&pt,3);
SelectObject(hdc, hOldPen);
}
/*
**
** Subclass proc for frame window
**
*/
LONG WINAPI __export FrameWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
FRAME_ENTRY *pFrame = NULL;
/* get frame data */
pFrame = GetFrameEntry(GetParent(hWnd));
/* this frame doesn't have and data so use default proc */
if(!pFrame)
return DefWindowProc(hWnd,msg,wParam,lParam);
switch(msg)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hWnd,&ps);
PaintFrame(pFrame);
EndPaint(hWnd,&ps);
return 0L;
}
break;
case WM_NCDESTROY:
/* remove frame data for this window */
UnRegisterFrame(hWnd);
return 0L;
}
/* call original window procedure */
return CallWindowProc(pFrame->OldWndProc,hWnd,msg,wParam,lParam);
}
/*
**
** subclass proc for dialog box
**
*/
LONG WINAPI __export DlgWndProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
FRAME_ENTRY *pFrame = NULL;
/* get frame data for this dialog box */
pFrame = GetFrameEntry(hDlg);
/* if not data found, revert to default dialog proc */
if(!pFrame)
return DefDlgProc(hDlg,msg,wParam,lParam);
switch(msg)
{
case WM_LBUTTONDOWN:
{
int id;
/* check button click */
id = TabHit(hDlg,LOWORD(lParam),HIWORD(lParam));
/* if not -1, then is id of tab clicked on */
if(id != -1)
{
/* no sense repainting if not neccessary */
if(pFrame->nTopTab != id)
{
SetTopTab(hDlg,id);
/* force repaint */
UpdateTabs(hDlg);
}
}
}
break;
default:
break;
}
/* call original dialog proc */
return CallWindowProc(pFrame->OldDlgProc,hDlg,msg,wParam,lParam);
}
/*
**
** not much here...
**
*/
int WINAPI _WEP(int nSystemExit)
{
return 1;
}
/*
**
** Build tab control from list of dialog templates
**
*/
BOOL WINAPI __export BuildTabs(HWND hDlg,HINSTANCE hInst, UINT wFrameID,
const TAGTEMPLATE FAR *lpTemplates, int nNumTemplates)
{
int i;
HWND hWnd;
/* if maxed out abort */
if(nNextEntry == MAX_ENTRY)
return FALSE;
/* get handle to frame */
hWnd = GetDlgItem(hDlg,wFrameID);
/* store handles */
entries[nNextEntry].hWnd = hWnd;
entries[nNextEntry].hDlg = hDlg;
/* first time, define globals */
if(nNextEntry == 0)
RegisterLibrary();
/* subclass the frame and store old wndproc */
entries[nNextEntry].OldWndProc = (WNDPROC)SetWindowLong(hWnd,
GWL_WNDPROC,(DWORD)FrameWndProc);
/* subclass the dialog and store old wndproc */
entries[nNextEntry].OldDlgProc = (WNDPROC)SetWindowLong(hDlg,
GWL_WNDPROC,(DWORD)DlgWndProc);
/* clear everything out */
entries[nNextEntry].tab_list = NULL;
entries[nNextEntry].nTopTab = 0;
entries[nNextEntry].nNextTab = 0;
entries[nNextEntry].bUseShadow = FALSE;
nNextEntry++;
/* for each template create a tab */
for(i=0;i<nNumTemplates;i++)
if(!CreateSingleTab(hDlg,hInst,wFrameID,
(TAGTEMPLATE FAR *)&lpTemplates[i]))
return FALSE;
/* set first one on top as default */
SetTopTab(hDlg,0);
return TRUE;
}
/*
**
** create a single tab from template
**
*/
BOOL WINAPI CreateSingleTab(HWND hDlg,HINSTANCE hInst, UINT wFrameID,
TAGTEMPLATE FAR *lpTemplate)
{
FRAME_ENTRY *pFrame;
TAB_ENTRY *pNewTab;
/* pointer to info for this frame */
pFrame = GetFrameEntry(hDlg);
/* abort! */
if(!pFrame)
return -1;
/* alloc a new tab structure */
pNewTab = (TAB_ENTRY *)malloc(sizeof(TAB_ENTRY));
/* abort */
if(!pNewTab)
return -1;
/* alloc room for title and copy over */
pNewTab->name = (char *)malloc(strlen(lpTemplate->lpTitle)+1);
strcpy(pNewTab->name,lpTemplate->lpTitle);
/* new tab id and clear out data */
pNewTab->nTabID = pFrame->nNextTab++;
pNewTab->controls = NULL;
pNewTab->next = NULL;
/* if tab_list empty, set new tab to first in list */
if(pFrame->tab_list == NULL)
pFrame->tab_list = pNewTab;
else
/* append to end of linked list */
{
TAB_ENTRY *ptr;
ptr = pFrame->tab_list;
while(ptr->next)
ptr = ptr->next;
ptr->next = pNewTab;
}
/* create controls from template */
return MergeControlsIntoDlg(hDlg,wFrameID,hInst,pNewTab,lpTemplate->lpDlgTemplate);
}
/*
**
** add control to list of controls in pTab
**
*/
BOOL WINAPI __export AddControl(TAB_ENTRY *pTab, WORD wControlID)
{
TAB_CTL *pCtl;
if(!pTab)
return FALSE;
/* alloc new control structure and fill */
pCtl = (TAB_CTL *)malloc(sizeof(TAB_CTL));
/* abort if malloc failed */
if(!pCtl)
return FALSE;
/* save control data */
pCtl->wID = wControlID;
pCtl->next = NULL;
/*
* if list empty stick at the head otherwise append to the end
* of the list.
*/
if(pTab->controls == NULL)
pTab->controls = pCtl;
else
{
TAB_CTL *ptr;
ptr = pTab->controls;
while(ptr->next)
ptr = ptr->next;
ptr->next = pCtl;
}
return TRUE;
}
/*
**
** turn on/off shadow in tab's
**
*/
void WINAPI __export SetTabStyle(HWND hDlg, DWORD dwStyle)
{
FRAME_ENTRY *pFrame;
/* pointer to info for this frame */
pFrame = GetFrameEntry(hDlg);
/* abort! */
if(!pFrame)
return;
if(dwStyle & TAB_SHADOWTEXT)
pFrame->bUseShadow = TRUE;
else
pFrame->bUseShadow = FALSE;
}